"use strict";
exports.__esModule = true;
var form_validator_1 = require("./form-validator");
var object_1 = require("../utils/object");
function linked(target) {
    if (target.data.prop) {
        this.data.formItems[target.data.prop] = target;
    }
    if (target.setInForm) {
        target.setInForm();
    }
    if (!this.data.firstItem) {
        this.data.firstItem = target;
    }
}
function unlinked(target) {
    if (target.data.prop) {
        delete this.data.formItems[target.data.prop];
    }
}
Component({
    properties: {
        models: {
            type: Object,
            value: {},
            observer: '_modelChange'
        },
        rules: {
            // 格式是[{name, rules: {}}]
            type: Array,
            value: [],
            observer: '_rulesChange'
        },
        extClass: {
            type: String,
            value: ''
        }
    },
    data: {
        errors: {},
        formItems: {},
        firstItem: null
    },
    relations: {
        '../cell/cell': {
            type: 'descendant',
            linked: linked,
            unlinked: unlinked
        },
        '../checkbox-group/checkbox-group': {
            type: 'descendant',
            linked: linked,
            unlinked: unlinked
        }
    },
    attached: function () {
        this.initRules();
        this.formValidator = new form_validator_1["default"](this.data.models, this.data.newRules);
    },
    methods: {
        initRules: function (rules) {
            var newRules = {};
            (rules || this.data.rules).forEach(function (rule) {
                if (rule.name && rule.rules) {
                    newRules[rule.name] = rule.rules || [];
                }
            });
            this.setData({ newRules: newRules });
            return newRules;
        },
        _modelChange: function (newVal, oldVal) {
            var _this = this;
            if (!this.formValidator) {
                return newVal;
            }
            // 这个必须在前面
            this.formValidator.setModel(newVal);
            var diffObj = (0, object_1.diffObject)(oldVal, newVal);
            if (diffObj) {
                var isValid_1 = true;
                var errors_1 = [];
                var errorMap_1 = {};
                Object.keys(diffObj).forEach(function (k) {
                    _this.formValidator.validateField(k, diffObj[k], function (isValided, error) {
                        if (error && error[k]) {
                            errors_1.push(error[k]);
                            errorMap_1[k] = error[k];
                        }
                        isValid_1 = isValided;
                    });
                });
                this._showErrors(diffObj, errorMap_1);
                this.triggerEvent(isValid_1 ? 'success' : 'fail', isValid_1 ? { trigger: 'change' } : { errors: errors_1, trigger: 'change' });
            }
            return newVal;
        },
        _rulesChange: function (newVal) {
            var newRules = this.initRules(newVal);
            if (this.formValidator) {
                this.formValidator.setRules(newRules);
            }
            return newVal;
        },
        _showAllErrors: function (errors) {
            var _this = this;
            Object.keys(this.data.newRules).forEach(function (k) {
                _this._showError(k, errors && errors[k]);
            });
        },
        _showErrors: function (objs, errors) {
            var _this = this;
            Object.keys(objs).forEach(function (k) {
                _this._showError(k, errors && errors[k]);
            });
        },
        _showError: function (prop, error) {
            var formItem = this.data.formItems[prop];
            if (formItem && formItem.data.showError) {
                formItem.setError(error);
            }
        },
        validate: function (cb) {
            var _this = this;
            return this.formValidator.validate(function (isValid, errors) {
                _this._showAllErrors(errors);
                var handleError = _this.handleErrors(errors);
                _this.triggerEvent(isValid ? 'success' : 'fail', isValid ? { trigger: 'validate' } : { errors: handleError, trigger: 'validate' });
                cb && cb(isValid, handleError);
            });
        },
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        validateField: function (name, value, cb) {
            var _this = this;
            if (cb === void 0) { cb = function (v, error) {
                if (error === void 0) { error = null; }
            }; }
            return this.formValidator.validateField(name, value, function (isValid, errors) {
                _this._showError(name, errors);
                var handleError = _this.handleErrors(errors);
                _this.triggerEvent(isValid ? 'success' : 'fail', isValid ? { trigger: 'validate' } : { errors: handleError, trigger: 'validate' });
                cb && cb(isValid, handleError);
            });
        },
        handleErrors: function (errors) {
            if (errors) {
                var newErrors_1 = [];
                this.data.rules.forEach(function (rule) {
                    if (errors[rule.name]) {
                        errors[rule.name].name = rule.name;
                        newErrors_1.push(errors[rule.name]);
                    }
                });
                return newErrors_1;
            }
            return errors;
        },
        addMethod: function (ruleName, method) {
            return this.formValidator.addMethod(ruleName, method);
        }
    }
});
exports["default"] = form_validator_1["default"];
